package com.ruicar.afs.cloud.batch.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.batch.entity.AfsBatchInfo;
import com.ruicar.afs.cloud.batch.enums.BatchType;
import com.ruicar.afs.cloud.batch.enums.HolidayMode;
import com.ruicar.afs.cloud.batch.enums.SystemStatus;
import com.ruicar.afs.cloud.batch.frame.control.BatchHelper;
import com.ruicar.afs.cloud.batch.mapper.AfsBatchInfoMapper;
import com.ruicar.afs.cloud.batch.service.AfsBatchInfoService;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.data.datasource.annotation.DS;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class AfsBatchInfoServiceImpl extends ServiceImpl<AfsBatchInfoMapper, AfsBatchInfo> implements AfsBatchInfoService {


    private void convertAfsBatchInfoFromMap(Map systemInfo,AfsBatchInfo afsBatchInfo){
        afsBatchInfo.setBatchDate(systemInfo.get("batchDate").toString());
        afsBatchInfo.setLastBatchDate(systemInfo.get("lastBatchDate").toString());
        afsBatchInfo.setLastWorkDay(systemInfo.get("lastWorkDay").toString());
        afsBatchInfo.setSystemName(systemInfo.get("systemName").toString());
        afsBatchInfo.setErrorNoticeConfig(systemInfo.get("errorNoticeConfig").toString());
        afsBatchInfo.setLiveThreadNum(Integer.valueOf(String.valueOf(systemInfo.get("liveThreadNum"))));
        afsBatchInfo.setHolidayMode((HolidayMode) AfsEnumUtil.getEnum(systemInfo.get("holidayMode").toString(), HolidayMode.class));
        afsBatchInfo.setSystemStatus((SystemStatus) AfsEnumUtil.getEnum(systemInfo.get("systemStatus").toString(), SystemStatus.class));
        afsBatchInfo.setBatchType((BatchType) AfsEnumUtil.getEnum(systemInfo.get("batchType").toString(), BatchType.class));
    }

    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    public AfsBatchInfo getSystemBatchInfo(String systemName) {
        Map systemInfo = this.baseMapper.selectSystem(systemName);
        if(systemInfo==null||systemInfo.size()==0){
            return null;
        }
        AfsBatchInfo afsBatchInfo = new AfsBatchInfo();
        convertAfsBatchInfoFromMap(systemInfo,afsBatchInfo);
        return afsBatchInfo;
    }

    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    public AfsBatchInfo getSystemBatchInfoWithOutUpdate(String systemName) {
        Map systemInfo = this.baseMapper.querySystemNameWithUpdate(systemName);
        if(systemInfo==null||systemInfo.size()==0){
            return null;
        }
        AfsBatchInfo afsBatchInfo = new AfsBatchInfo();
        convertAfsBatchInfoFromMap(systemInfo,afsBatchInfo);
        return afsBatchInfo;
    }


    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    @Transactional(rollbackFor = Exception.class)
    public void switchDay(String systemName) {
        AfsBatchInfo dbAfsBatchInfo = this.getOne(Wrappers.<AfsBatchInfo>lambdaQuery().eq(AfsBatchInfo::getSystemName,systemName));
        if(dbAfsBatchInfo==null){
            throw   new AfsBaseException("切日失败，系统编号"+systemName+"不存在");
        }
        if(dbAfsBatchInfo.getSystemStatus()==SystemStatus.NORMAL){
            throw   new AfsBaseException("切日失败，系统编号"+systemName+"处于正常状态");
        }
        AfsBatchInfo afsBatchInfo = new AfsBatchInfo();
        afsBatchInfo.setSystemName(dbAfsBatchInfo.getSystemName());
        afsBatchInfo.setBatchDate(dbAfsBatchInfo.getBatchDate());
        Date date = DateUtil.parse(afsBatchInfo.getBatchDate(), DatePattern.PURE_DATE_PATTERN);
        Calendar calendar = DateUtil.calendar(date);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        String nextDay = DateUtil.format(calendar.getTime(), DatePattern.PURE_DATE_PATTERN);
        afsBatchInfo.setLastBatchDate(afsBatchInfo.getBatchDate());
        if(!BatchHelper.isHoliday(afsBatchInfo.getBatchDate())) {
            afsBatchInfo.setLastWorkDay(afsBatchInfo.getBatchDate());
        }
        if(dbAfsBatchInfo.getHolidayMode()==HolidayMode.HUMAN_DAY_BY_DAY||dbAfsBatchInfo.getHolidayMode()==HolidayMode.REPEAT_DAY_BY_DAY_AUTO) {
            afsBatchInfo.setBatchDate(nextDay);
            try {
                BatchHelper.isHoliday(afsBatchInfo.getBatchDate());
            } catch (Exception e) {
                log.error("切日后节假日未维护，切日失败");
                throw new RuntimeException("切日后节假日未维护，切日失败");
            }
            this.updateById(afsBatchInfo);
        }else if(dbAfsBatchInfo.getHolidayMode()==HolidayMode.DIRECT_RUN_TO_TARGET){
            nextDay = BatchHelper.nextWorkDay(afsBatchInfo.getBatchDate());
            afsBatchInfo.setBatchDate(nextDay);
            try {
                BatchHelper.isHoliday(afsBatchInfo.getBatchDate());
            } catch (Exception e) {
                log.error("切日后节假日未维护，切日失败");
                throw new RuntimeException("切日后节假日未维护，切日失败");
            }
            this.updateById(afsBatchInfo);
        }
    }


    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    @Transactional
    public void changeBatchToNormal(String systemName, BatchType batchType) {
        AfsBatchInfo afsBatchInfo = this.getOne(Wrappers.<AfsBatchInfo>lambdaQuery().eq(AfsBatchInfo::getSystemName,systemName));
        if(afsBatchInfo==null){
            throw   new AfsBaseException("状态修改失败，系统编号"+systemName+"不存在");
        }
        if(afsBatchInfo.getSystemStatus()==SystemStatus.NORMAL){
            throw   new AfsBaseException("状态修改失败，系统编号"+systemName+"处于正常状态");
        }
        //在自动重复执行模式下 非节假日才设置成正常
        if(BatchHelper.isHoliday(afsBatchInfo.getBatchDate())&& afsBatchInfo.getHolidayMode()==HolidayMode.REPEAT_DAY_BY_DAY_AUTO) {
            return;
        }
        this.update(Wrappers.<AfsBatchInfo>lambdaUpdate().eq(AfsBatchInfo::getSystemName,systemName).set(AfsBatchInfo::getBatchType,batchType).set(AfsBatchInfo::getSystemStatus,SystemStatus.NORMAL));
    }

    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    @Transactional
    public void changeBatchToNormalConsole(String systemName) {
        AfsBatchInfo afsBatchInfo = this.getOne(Wrappers.<AfsBatchInfo>lambdaQuery().eq(AfsBatchInfo::getSystemName,systemName));
        if(afsBatchInfo==null){
            throw   new AfsBaseException("状态修改失败，系统编号"+systemName+"不存在");
        }
        if(afsBatchInfo.getSystemStatus()==SystemStatus.NORMAL){
            throw   new AfsBaseException("状态修改失败，系统编号"+systemName+"处于正常状态");
        }
//        afsBatchInfo.setSystemStatus(SystemStatus.NORMAL);
        this.update(Wrappers.<AfsBatchInfo>lambdaUpdate().eq(AfsBatchInfo::getSystemName,systemName).set(AfsBatchInfo::getSystemStatus,SystemStatus.NORMAL));
    }

    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    @Transactional
    public void changeBatchToError(String systemName) {
        AfsBatchInfo afsBatchInfo = this.getOne(Wrappers.<AfsBatchInfo>lambdaQuery().eq(AfsBatchInfo::getSystemName,systemName));
        if(afsBatchInfo==null){
           throw  new AfsBaseException("状态修改失败，系统编号"+systemName+"不存在");
        }
        if(afsBatchInfo.getSystemStatus()==SystemStatus.NORMAL){
            throw  new AfsBaseException("状态修改失败，系统编号"+systemName+"处于正常状态");
        }
        this.update(Wrappers.<AfsBatchInfo>lambdaUpdate().eq(AfsBatchInfo::getSystemName,systemName).set(AfsBatchInfo::getSystemStatus,SystemStatus.ERROR));
    }

    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    public void addRunThreadNum(String systemName,int num,String symbol) {
        log.info("========系统[{}]线程数加[{}]，符号[{}]========",systemName,num,symbol);
        this.baseMapper.addRunThreadNum(systemName,num);
    }

    @Override
    @DS(CommonConstants._BASE_DS_NAME)
    public void cutDown(String systemName, int num,String symbol) {
        log.info("========系统[{}]线程数减[{}]，符号[{}]========",systemName,num,symbol);
        this.baseMapper.cutDown(systemName,num);
    }
}
